﻿#pragma once

#include "Misc/EngineEditorMacros.h"
#include "Framework/EditorModelSubsystem.h"
#include "Misc/EngineEditorMacros.h"
#include "PageArea/EditorPageAreaManagerModel.h"
#include "Path/Path.h"
#include "Containers/ScriptDelegateImplement.h"
#include "EditorWindowGroupModel.m.h"

class REditorMainWindowModel;
class REditorWindowModel;
class REditorPageModel;
class REditorSubwindowModel;

//store all data of a window group
//also the root object of all model
RCLASS(ExtraHeader=["Window/EditorMainWindowModel.h", "Window/EditorWindowModel.h","Pages/EditorPageModel.h"])
class ENGINEEDITOR_API REditorWindowGroupModel : public REditorModelSubsystem
{
    ROBJECT

public:
    REditorWindowGroupModel();
    virtual void Initialize() override;
    virtual void Deinitialize() override;
    
    static REditorWindowGroupModel* Get();
    
    void CreateAndShowMainWindow();
    void CreateMainWindow();
    TSharedObjectPtr<REditorSubwindowModel> CreateSubwindow();

    RFIELD()
    TSharedObjectPtr<REditorMainWindowModel> MainWindow;


    void RegisterWindow(TSharedObjectPtr<REditorWindowModel> Window);
    void UnregisterWindow(TSharedObjectPtr<REditorWindowModel> Window);
    TMultiCastDelegate<TSharedObjectPtr<REditorWindowModel>> OnWindowRegistered;
    TMultiCastDelegate<TSharedObjectPtr<REditorWindowModel>> OnWindowUnregistered;
    TVector<TSharedObjectPtr<REditorWindowModel>> GetWindows() const;

    void CloseWindow(TSharedObjectPtr<REditorWindowModel> Window);
protected:
    RFIELD()
    TVector<TSharedObjectPtr<REditorWindowModel>> Windows;

public:
    TSharedObjectPtr<REditorPageAreaManagerModel> GetFocusedPageAreaManager() const;
    void FocusePageAreaManager(TSharedObjectPtr<REditorPageAreaManagerModel> InPageArea);
    
    //获取当前聚焦页面所在的区域
    TSharedObjectPtr<REditorPageAreaModel> GetFocusedPageArea() const;

    //当前正在编辑的文件
    TSharedObjectPtr<REditorPageModel> GetFocusedPage() const;
    SPath GetCurrentFilePath() const;
    void NotifyCurrentPageChanged();
    RFIELD()
    TScriptDelegate<void(TSharedObjectPtr<REditorPageModel>)> OnCurrentPageChanged;

    void OpenPage(TSharedObjectPtr<REditorPageModel> Page);
    TSharedObjectPtr<REditorPageModel> CreatePage(const SPath& FilePath);
    void ReplacePage(TSharedObjectPtr<REditorPageModel> OldPage, TSharedObjectPtr<REditorPageModel> NewPage);
    void ReopenPage(TSharedObjectPtr<REditorPageModel> InOpenedPage);

    RFUNCTION()
    void CloseAllPages();

    //依据文件路径打开文件,如果文件已经打开，则激活该文件
    //有些页面没有文件路径，比如欢迎页面，需要使用PageID打开
    void OpenFile(const SPath& FilePath);

    //依据页面ID打开文件,如果文件已经打开，则激活该文件
    void OpenPage(
        const CString& PageID
        ,TScriptDelegate<
            TSharedObjectPtr<REditorPageModel>()
            > CreatePageMethod 
        );

protected:

    //当前用户关注的根页面区域
    RFIELD()
    TSharedObjectPtr<REditorPageAreaManagerModel> FocusedPageAreaManager;


public:
    //get the object that is focused in the focused page
    TSharedObjectPtr<RObject> GetFocusedObject() const;

    //invoke when the focused object is changed in page
    void NotifyFocusedObjectChanged();

    RFIELD()
    TScriptDelegate<void(TSharedObjectPtr<RObject>)> OnFocusedObjectChanged;

protected:
    RFUNCTION()
    void OnPageFocusedObjectChanged(TSharedObjectPtr<RObject> InObject);

    //the former focused object
    //used to check if the focused object is changed
    TSharedObjectPtr<RObject> FormerFocusedObject;

};
